home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / qdeck / print / xprtscr.c < prev   
Encoding:
C/C++ Source or Header  |  1994-08-11  |  17.4 KB  |  762 lines

  1. /**************************************************************************
  2.  *
  3.  * FILENAME:    xprtscr.c
  4.  *
  5.  * DESCRIPTION:
  6.  *  A sample print screen program.
  7.  *
  8.  * PUBLIC FUNCTIONS:
  9.  *  None
  10.  *
  11.  * NOTES:
  12.  *  Syntax: xprtscr [-printer <printer>] [-display <display>]
  13.  *
  14.  *  Copyright (c) Quarterdeck Office Systems, Inc. 1992
  15.  *
  16.  * PVCS INFO:
  17.  *  $Header::xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$
  18.  *
  19.  * CHANGES:
  20.  *  $Log::xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx$
  21.  *
  22.  **************************************************************************
  23.  
  24. static char id_xprtscr_c[3][] =  {
  25.                                 "$Workfile::xxxxxxxxxxxxxxxxxxxxxxxxxx$\n",
  26.                                 "$Revision::xxxxxxxxxxxxxxxxxxxxxxxxxx$\n",
  27.                                 "    $Date::xxxxxxxxxxxxxxxxxxxxxxxxxx$\n"
  28.                                 };
  29.         
  30. /*----- compilation and control switches --------------------------------*/
  31.  
  32.  
  33. /**************************************************************************
  34.  *  INCLUDE FILES
  35.  *************************************************************************/
  36.  
  37. /*----- system and platform files ---------------------------------------*/
  38.  
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42.  
  43. #include <X11/Xlib.h>
  44.  
  45. /*----- program files ---------------------------------------------------*/
  46.  
  47.  
  48. /**************************************************************************
  49.  *  EXTERNAL REFERENCES
  50.  *************************************************************************/
  51.  
  52. /*----- data declarations -----------------------------------------------*/
  53.  
  54. /*----- function prototypes ---------------------------------------------*/
  55.  
  56.  
  57. /**************************************************************************
  58.  *  PUBLIC DECLARATIONS
  59.  *************************************************************************/
  60.  
  61. /*----- context ---------------------------------------------------------*/
  62.  
  63. /*----- data declarations -----------------------------------------------*/
  64.  
  65. /*----- function prototypes ---------------------------------------------*/
  66.  
  67.  
  68. /**************************************************************************
  69.  *  PRIVATE DECLARATIONS
  70.  *************************************************************************/
  71.  
  72. /*----- context ---------------------------------------------------------*/
  73.  
  74. #define LOCAL_DISPLAY       ":0"
  75. #define LOCAL_PRINTER       ":7"
  76. #define PRINT_SCREEN        92
  77.  
  78. typedef enum
  79. {
  80.     FALSE = 0, TRUE
  81. }               BOOL;
  82.  
  83. /*----- data declarations -----------------------------------------------*/
  84.  
  85. /*----- Set as a result of command line options. ------------------------*/
  86.  
  87. char           *pPrinterName = (char *) NULL;   /* Display name for prtr */
  88. char           *pDisplayName = (char *) NULL;   /* Display name for disp */
  89.  
  90. /*----- X data structures for displaying. -------------------------------*/
  91.  
  92. Display        *pDisplay;       /* X display for display. */
  93. int             ScreenNumber;    /* X screen number for printer. */
  94. Window          DisplayRoot;    /* X window for display. */
  95. GC              DisplayContext; /* X graphics context for display. */
  96.  
  97. /*----- X data structures for printing. ---------------------------------*/
  98.  
  99. Display        *pPrinter;       /* X display for printer. */
  100. Window          Page;           /* X window for printer. */
  101. GC              PrintContext;   /* X graphics context for printer. */
  102.  
  103. /*----- Page size information. ------------------------------------------*/
  104.  
  105. unsigned int    PageWidthInPixels;  /* Width of printer page in pixels. */
  106. unsigned int    PageHeightInPixels; /* Height of printer page in pixels. */
  107.  
  108. /*----- function prototypes ---------------------------------------------*/
  109.  
  110. int             main(int argc, char **argv);
  111. void            ParseArguments(int argc, char **argv);
  112. void            Usage(void);
  113. void            GrabKeys(void);
  114. void            EventLoop(void);
  115. void            PrintScreen(void);
  116. void            StartPrintJob(void);
  117. void            FinishPrintJob(void);
  118. void            ReleaseKeys(void);
  119.  
  120. /*----- macros ----------------------------------------------------------*/
  121.  
  122.  
  123.  
  124. /**************************************************************************
  125.  *  PUBLIC FUNCTION DECLARATIONS
  126.  *************************************************************************/
  127.  
  128.  
  129. /**************************************************************************
  130.  *  PRIVATE FUNCTION DECLARATIONS
  131.  *************************************************************************/
  132.  
  133.  
  134. /**************************************************************************
  135.  * NAME:
  136.  *  main(int argc, char **argv)
  137.  *
  138.  * DESCRIPTION:
  139.  *  Program entry point.
  140.  *
  141.  * INPUTS:
  142.  *  PARAMATERS:
  143.  *      int    argc     Count of command line arguments
  144.  *      char **argv     Array of pointers to command line argument strings
  145.  *
  146.  *  GLOBALS:
  147.  *      None
  148.  *
  149.  * OUTPUTS:
  150.  *  PARAMATERS:
  151.  *      None
  152.  *
  153.  *  GLOBALS:
  154.  *      None
  155.  *
  156.  *  RETURN:
  157.  *      Exits to DOS on completion.
  158.  *
  159.  * NOTES:
  160.  *  Proposed enhancements
  161.  *      Allow for printing of multiple files.
  162.  *
  163.  * CHANGES:
  164.  *  None
  165.  */
  166.  
  167. int
  168. main(int argc, char **argv)
  169. {
  170.  
  171.     /*********************************************************************/
  172.  
  173.  
  174.     /****** CODE *********************************************************/
  175.  
  176.     ParseArguments(argc, argv);
  177.  
  178.     /*----- Establish connection to X Print Server ----------------------*/
  179.  
  180.     if (pDisplayName == (char *) NULL)
  181.         pDisplayName = LOCAL_DISPLAY;
  182.  
  183.     pDisplay     = XOpenDisplay(pDisplayName);
  184.     ScreenNumber = DefaultScreen(pDisplay);
  185.     DisplayRoot  = RootWindow(pDisplay, ScreenNumber);
  186.  
  187.     if (pDisplay == (Display *) NULL)
  188.         {
  189.         fprintf(stderr,
  190.                 "xprtscr: cannot connect to X display %s\n",
  191.                 pDisplayName);
  192.  
  193.         exit(-1);
  194.         }
  195.  
  196.  
  197.     GrabKeys();
  198.  
  199.     EventLoop();
  200.  
  201.     ReleaseKeys();
  202.  
  203.  
  204.     /*----- Close Display -----------------------------------------------*/
  205.  
  206.     XCloseDisplay(pDisplay);
  207.  
  208.     exit(0);
  209. }
  210.  
  211.  
  212. /**************************************************************************
  213.  * NAME:
  214.  *  ParseArguments(int argc, char ** argv)
  215.  *
  216.  * DESCRIPTION:
  217.  *  Parse command line arguments and set corresponding global variables.
  218.  *
  219.  * INPUTS:
  220.  *  PARAMATERS:
  221.  *      int    argc     Count of command line arguments
  222.  *      char **argv     Array of pointers to command line argument strings
  223.  *
  224.  *  GLOBALS:
  225.  *      None
  226.  *
  227.  * OUTPUTS:
  228.  *  PARAMATERS:
  229.  *      None
  230.  *
  231.  *  GLOBALS:
  232.  *      None
  233.  *
  234.  *  RETURN:
  235.  *      None
  236.  *
  237.  * NOTES:
  238.  *  None
  239.  *
  240.  * CHANGES:
  241.  *  None
  242.  */
  243.  
  244. void
  245. ParseArguments(int argc, char **argv)
  246. {
  247.  
  248.     /*********************************************************************/
  249.  
  250.     int             ArgumentIndex;
  251.  
  252.     /****** CODE *********************************************************/
  253.  
  254.     for (ArgumentIndex = 1; ArgumentIndex < argc; ArgumentIndex++)
  255.         {
  256.         if (strcmp(argv[ArgumentIndex], "-printer") == 0)
  257.             {
  258.             if (++ArgumentIndex >= argc)
  259.                 Usage();
  260.  
  261.             pPrinterName = argv[ArgumentIndex];
  262.  
  263.             continue;
  264.             }
  265.  
  266.         if (strcmp(argv[ArgumentIndex], "-display") == 0)
  267.             {
  268.             if (++ArgumentIndex >= argc)
  269.                 Usage();
  270.  
  271.             pDisplayName = argv[ArgumentIndex];
  272.  
  273.             continue;
  274.             }
  275.  
  276.         Usage();
  277.         }
  278. }
  279.  
  280.  
  281. /**************************************************************************
  282.  * NAME:
  283.  *  Usage(void)
  284.  *
  285.  * DESCRIPTION:
  286.  *  Prints usage message and then exits to DOS.
  287.  *
  288.  * INPUTS:
  289.  *  PARAMATERS:
  290.  *      None
  291.  *
  292.  *  GLOBALS:
  293.  *      None
  294.  *
  295.  * OUTPUTS:
  296.  *  PARAMATERS:
  297.  *      None
  298.  *
  299.  *  GLOBALS:
  300.  *      None
  301.  *
  302.  *  RETURN:
  303.  *      None
  304.  *
  305.  * NOTES:
  306.  *  This should be updated when command line switches are added.
  307.  *
  308.  * CHANGES:
  309.  *  None
  310.  */
  311.  
  312. void
  313. Usage(void)
  314. {
  315.  
  316.     /*********************************************************************/
  317.  
  318.  
  319.     /****** CODE *********************************************************/
  320.  
  321.     fprintf(stderr, "usage: xprtscr [-printer <printer>] [-display <display>]\n");
  322.  
  323.     exit(1);
  324. }
  325.  
  326.  
  327. /**************************************************************************
  328.  * NAME:
  329.  *  GrabKeys(void)
  330.  *
  331.  * DESCRIPTION:
  332.  *  Sets a passive grap on the PrintScreen key.
  333.  *
  334.  * INPUTS:
  335.  *  PARAMATERS:
  336.  *      None
  337.  *
  338.  *  GLOBALS:
  339.  *      None
  340.  *
  341.  * OUTPUTS:
  342.  *  PARAMATERS:
  343.  *      None
  344.  *
  345.  *  GLOBALS:
  346.  *      None
  347.  *
  348.  *  RETURN:
  349.  *      None
  350.  *
  351.  * NOTES:
  352.  *  Grab the keys that we want.
  353.  *
  354.  * CHANGES:
  355.  *  None
  356.  */
  357.  
  358. void
  359. GrabKeys(void)
  360. {
  361.  
  362.     /*********************************************************************/
  363.  
  364.     /****** CODE *********************************************************/
  365.  
  366.     XGrabKey(pDisplay,
  367.              PRINT_SCREEN,
  368.              0,
  369.              DisplayRoot,
  370.              False,
  371.              GrabModeSync,
  372.              GrabModeAsync);
  373.  
  374. }
  375.  
  376.  
  377. /**************************************************************************
  378.  * NAME:
  379.  *  EventLoop(void)
  380.  *
  381.  * DESCRIPTION:
  382.  *  This is the main event loop.  It sets up the events it is interested in
  383.  *  and then loops waiting for these events.
  384.  *
  385.  * INPUTS:
  386.  *  PARAMATERS:
  387.  *      None
  388.  *
  389.  *  GLOBALS:
  390.  *      None
  391.  *
  392.  * OUTPUTS:
  393.  *  PARAMATERS:
  394.  *      None
  395.  *
  396.  *  GLOBALS:
  397.  *      None
  398.  *
  399.  *  RETURN:
  400.  *      None
  401.  *
  402.  * NOTES:
  403.  *  Grab the keys that we want.
  404.  *
  405.  * CHANGES:
  406.  *  None
  407.  */
  408.  
  409. void
  410. EventLoop(void)
  411. {
  412.  
  413.     /*********************************************************************/
  414.  
  415.     XEvent  Event;
  416.  
  417.     /****** CODE *********************************************************/
  418.  
  419.     fprintf(stdout, "Waiting for the  PrintScrn key to be pressed...\n");
  420.     XSelectInput(pDisplay, 
  421.                  DisplayRoot,
  422.                  StructureNotifyMask | KeyPressMask | KeyReleaseMask);
  423.  
  424.     while (1)
  425.         {
  426.         XNextEvent(pDisplay, &Event);
  427.  
  428.         switch (Event.type)
  429.             {
  430.             case KeyPress:
  431. #ifdef DEBUG
  432.                 fprintf(stdout, "KeyPress: \n");
  433. #endif
  434.                 fprintf(stdout, "Printing screen\n");
  435.                 PrintScreen();
  436.                 break;
  437.  
  438.             case KeyRelease:
  439. #ifdef DEBUG
  440.                 fprintf(stdout, "KeyRelease: \n");
  441. #endif
  442.                 break;
  443.  
  444.             case DestroyNotify:
  445.                 return;
  446.                 break;
  447.  
  448.             default:
  449.                 fprintf(stdout, "Unrecognized event: %d\n", Event.type);
  450.             }
  451.         }
  452. }
  453.  
  454.  
  455. /**************************************************************************
  456.  * NAME:
  457.  *  PrintScreen(void)
  458.  *
  459.  * DESCRIPTION:
  460.  *  Get the screen image and send it to the X printer
  461.  *
  462.  * INPUTS:
  463.  *  PARAMATERS:
  464.  *      None
  465.  *
  466.  *  GLOBALS:
  467.  *      None
  468.  *
  469.  * OUTPUTS:
  470.  *  PARAMATERS:
  471.  *      None
  472.  *
  473.  *  GLOBALS:
  474.  *      None
  475.  *
  476.  *  RETURN:
  477.  *      None
  478.  *
  479.  * NOTES:
  480.  *  Release the keys that were grabbed.
  481.  *
  482.  * CHANGES:
  483.  *  None
  484.  */
  485.  
  486. void
  487. PrintScreen(void)
  488. {
  489.  
  490.     /*********************************************************************/
  491.  
  492.     XWindowAttributes   WindowAttributes;
  493.     XImage             *pImage;
  494.     Status              status;
  495.  
  496.     int                 ImageX;
  497.     int                 ImageY;
  498.  
  499.     unsigned int        ImageWidth;
  500.     unsigned int        ImageHeight;
  501.  
  502.     unsigned int        PixelsPerByte;
  503.     unsigned int        BytesPerLine;
  504.  
  505.     /****** CODE *********************************************************/
  506.  
  507.     StartPrintJob();
  508.  
  509.     status = XGetWindowAttributes(pDisplay, DisplayRoot, &WindowAttributes);
  510.  
  511.     if(status == 0)
  512.         {
  513.         fprintf(stderr, "Can't get target window attributes.");
  514.         exit(1);
  515.         }
  516.  
  517.     /*
  518.      * Server can't currently handle GetImage > 16K so we do multiple
  519.      * GetImages.
  520.      */
  521.  
  522.     ImageWidth    = WindowAttributes.width;
  523.     PixelsPerByte = 8 / WindowAttributes.depth;
  524.     BytesPerLine  = ImageWidth / PixelsPerByte;
  525.     ImageHeight   = 0x2000 / BytesPerLine;
  526.  
  527.     ImageX = 0;
  528.  
  529.     for (ImageY = 0; ImageY < WindowAttributes.height - 1; ImageY += ImageHeight)
  530.         {
  531.         if (ImageY + ImageHeight > WindowAttributes.height)
  532.             ImageHeight = WindowAttributes.height - ImageY;
  533.  
  534. #ifdef DEBUG
  535.         fprintf(stdout, "%d, %d, %d, %d\n", ImageX, ImageY, ImageWidth, ImageHeight);
  536. #endif
  537.  
  538.         pImage = XGetImage(pDisplay,
  539.                            DisplayRoot,
  540.                            ImageX,
  541.                            ImageY,
  542.                            ImageWidth,
  543.                            ImageHeight,
  544.                            AllPlanes,
  545.                            ZPixmap);
  546.  
  547.         if (pImage == (XImage *) NULL)
  548.             {
  549.             fprintf(stderr, "Unable to get image\n");
  550.             exit(1);
  551.             }
  552.  
  553.         XPutImage(pPrinter,
  554.                   Page,
  555.                   PrintContext,
  556.                   pImage,
  557.                   0,
  558.                   0,
  559.                   ImageX,
  560.                   ImageY,
  561.                   ImageWidth,
  562.                   ImageHeight);
  563.  
  564.         XDestroyImage(pImage);
  565.         XFlush(pPrinter);
  566.         }
  567.  
  568.     FinishPrintJob();
  569. }
  570.  
  571.  
  572. /**************************************************************************
  573.  * NAME:
  574.  *  StartPrintJob(void)
  575.  *
  576.  * DESCRIPTION:
  577.  *  Connect to X Print Server and setup up printing environment.
  578.  *
  579.  * INPUTS:
  580.  *  PARAMATERS:
  581.  *      None
  582.  *
  583.  *  GLOBALS:
  584.  *      char  *pPrinterName     Pointer to display name for printer.
  585.  *      double FontSize         Font size to use when printing (in points).
  586.  *
  587.  * OUTPUTS:
  588.  *  PARAMATERS:
  589.  *      None
  590.  *
  591.  *  GLOBALS:
  592.  *      Display     *pPrinter;              X display for printer.
  593.  *      Window       Page;                  X window for printer.
  594.  *      GC           PrintContext;          X graphics context for printer.
  595.  *      unsigned int PageWidthInPixels      Width of print page in pixels.
  596.  *      unsigned int PageHeightInPixels     Height of print page in pixels.
  597.  *
  598.  *  RETURN:
  599.  *      None
  600.  *
  601.  * NOTES:
  602.  *  Basic steps for starting print job.
  603.  *      Connect to X Print Server.
  604.  *      Query for page size and resolution.
  605.  *      Create window that will represent the printed page.
  606.  *      Create X font string and load printer font.
  607.  *      Create graphics context for printing.
  608.  *
  609.  * CHANGES:
  610.  */
  611.  
  612. void
  613. StartPrintJob(void)
  614. {
  615.  
  616.     /*********************************************************************/
  617.  
  618.     int             ScreenNumber;    /* X screen number for printer. */
  619.  
  620.     /****** CODE *********************************************************/
  621.  
  622.     /*----- Establish connection to X Print Server ----------------------*/
  623.  
  624.     if (pPrinterName == (char *) NULL)
  625.         pPrinterName = LOCAL_PRINTER;
  626.  
  627.     pPrinter = XOpenDisplay(pPrinterName);
  628.  
  629.     if (pPrinter == NULL)
  630.         {
  631.         fprintf(stderr,
  632.                 "xprint: cannot connect to X printer %s\n",
  633.                 pPrinterName);
  634.  
  635.         exit(-1);
  636.         }
  637.  
  638.  
  639.     /*----- Query information from XLib ---------------------------------*/
  640.  
  641.     ScreenNumber = DefaultScreen(pPrinter);
  642.  
  643.     PageWidthInPixels = DisplayWidth(pPrinter, ScreenNumber);
  644.  
  645.     PageHeightInPixels = DisplayHeight(pPrinter, ScreenNumber);
  646.  
  647.     /*----- Create window that will represent the printed page. ---------*/
  648.  
  649.     Page = XCreateSimpleWindow(pPrinter,
  650.                                RootWindow(pPrinter, ScreenNumber),
  651.                                0,
  652.                                0,
  653.                                PageWidthInPixels,
  654.                                PageHeightInPixels,
  655.                                0,
  656.                                BlackPixel(pPrinter, ScreenNumber),
  657.                                WhitePixel(pPrinter, ScreenNumber));
  658.  
  659.     PrintContext = DefaultGC(pPrinter, ScreenNumber);
  660. }
  661.  
  662.  
  663. /**************************************************************************
  664.  * NAME:
  665.  *  FinishPrintJob(void)
  666.  *
  667.  * DESCRIPTION:
  668.  *  Closes connection to X Print Server.
  669.  *
  670.  * INPUTS:
  671.  *  PARAMATERS:
  672.  *      None
  673.  *
  674.  *  GLOBALS:
  675.  *      Display     *pPrinter               X display for printer
  676.  *      Window       Page;                  X window for printer.
  677.  *
  678.  * OUTPUTS:
  679.  *  PARAMATERS:
  680.  *      None
  681.  *
  682.  *  GLOBALS:
  683.  *      None
  684.  *
  685.  *  RETURN:
  686.  *      None
  687.  *
  688.  * NOTES:
  689.  *  An X print job is finished when the connection to the X Print Server is
  690.  *  closed.  A side effect of this is that the last page is automatically
  691.  *  ejected.
  692.  *
  693.  * CHANGES:
  694.  *  None
  695.  */
  696.  
  697. void
  698. FinishPrintJob(void)
  699. {
  700.  
  701.     /*********************************************************************/
  702.  
  703.  
  704.     /****** CODE *********************************************************/
  705.  
  706.     /*----- Free drawing window -----------------------------------------*/
  707.  
  708.     XDestroyWindow(pPrinter, Page);
  709.  
  710.     /*----- Close Display ending print jobs -----------------------------*/
  711.  
  712.     XCloseDisplay(pPrinter);
  713. }
  714.  
  715.  
  716. /**************************************************************************
  717.  * NAME:
  718.  *  ReleaseKeys(void)
  719.  *
  720.  * DESCRIPTION:
  721.  *  Releases the passive grab on the PrintScreen key.
  722.  *
  723.  * INPUTS:
  724.  *  PARAMATERS:
  725.  *      None
  726.  *
  727.  *  GLOBALS:
  728.  *      None
  729.  *
  730.  * OUTPUTS:
  731.  *  PARAMATERS:
  732.  *      None
  733.  *
  734.  *  GLOBALS:
  735.  *      None
  736.  *
  737.  *  RETURN:
  738.  *      None
  739.  *
  740.  * NOTES:
  741.  *  Release the keys that were grabbed.
  742.  *
  743.  * CHANGES:
  744.  *  None
  745.  */
  746.  
  747. void
  748. ReleaseKeys(void)
  749. {
  750.  
  751.     /*********************************************************************/
  752.  
  753.     /****** CODE *********************************************************/
  754.  
  755.     XUngrabKey(
  756.              pDisplay,
  757.              PRINT_SCREEN,
  758.              0,
  759.              DisplayRoot
  760.             );
  761. }
  762.